package poker;

import java.util.ArrayList;

import enums.ActionType;

public class Rules 
{
	private static GameRound gameRound;

	static int numPlayers; 
	
	public static void SetGameRound(GameRound gr) 
	{ 
		gameRound = gr; 
		numPlayers = gr.getPlayersLeft();
	}
	
	public static boolean isCheckAllowed(Player player)
	{
		if(gameRound.getIsPreFlop())
		{
			if(gameRound.getPlayers().get((gameRound.getDealerPosition() + 2) % numPlayers) != player)
				return false;
			//if player has posted big blind and nobody have raised, checking is allowed
			for (Action action : gameRound.getPlayerActions()) 
			{
				if(action.getActionType() == ActionType.RAISE)
					return false;
			}
		}
		else
		{
			for (Action action : gameRound.getPlayerActions()) 
			{
				if(action.getActionType() == ActionType.BET || action.getActionType() == ActionType.RAISE)
					return false;
			}
		}
		return true;
	}
	
	public static boolean isRaiseAllowed(Player player)
	{
		return !(player.getBettingRoundCounter() == 0);
	}
	
	public static ArrayList<ActionType> getLegalActions(Player player)
	{
		ArrayList<ActionType> legalActions = new ArrayList<ActionType>();
		
		if(isCheckAllowed(player)) { legalActions.add(ActionType.CHECK); }
		else{legalActions.add(ActionType.CALL);}
	
		if(!isBetAllowed(player) && legalActions.contains(ActionType.BET))
				{legalActions.remove(ActionType.BET); }		
		if(!isRaiseAllowed(player) && legalActions.contains(ActionType.RAISE))
				{legalActions.remove(ActionType.RAISE); }		
		
		if(isBetAllowed(player)) { legalActions.add(ActionType.BET); }
		else if(isRaiseAllowed(player)) { legalActions.add(ActionType.RAISE); }		
		legalActions.add(ActionType.FOLD);
	
		return legalActions;		
	}
	
	private static boolean isBetAllowed(Player player) 
	{
		return gameRound.getCurrentBet() == 0;
	}

	public static boolean isBettingRoundOver() 
	{
		int folded = gameRound.getFolded();
		int playersLeft = numPlayers - folded;
		
		//Somebody haven't "spoken"
		if(gameRound.getPlayerActions().size() < numPlayers - folded)
			return false;
		
		//Only one player left
		if(folded == numPlayers - 1)
			return true;
		
		//Special case: no betting, but we have to call big blind
		if(gameRound.getIsPreFlop() && gameRound.getPlayerActions().size() >= numPlayers)
		{
			boolean raise = false;
			for (int i = 0; i < numPlayers - 1; i++) 
			{
				if(gameRound.getPlayerActions().get(i).getActionType() == ActionType.RAISE)
					raise = true;
			}
			
			if(gameRound.getPlayerActions().get(numPlayers - 1).getActionType() == ActionType.CHECK && !raise)
				return true;
		}
		
		//All have checked
		if(gameRound.getCurrentBet() == 0 && gameRound.getPlayerActions().size() >= playersLeft)
			return true;
		
		if(!gameRound.getIsPreFlop())
		{
			int checks = 0;
			for(int i = 0; i < playersLeft; i++)
			{
				int actionIndex = playersLeft - 1 - i;
				if(gameRound.getPlayerActions().get(actionIndex).getActionType() == ActionType.CHECK)
					checks++;
			}
			if(checks == playersLeft)
				return true;
		}
		
		//check the X last actions, if one of the actions is bet or raise we have to check if everybody has called the bet/raise. 
		int activePlayers = playersLeft;
	
		if(gameRound.getLastRaisedPointer() != -1)
		{
			for (int j = gameRound.getLastRaisedPointer(); j < gameRound.getPlayerActions().size(); j++) 
			{
				if(gameRound.getPlayerActions().get(j).getActionType() == ActionType.FOLD)
					activePlayers++;
			}

			int actionsAfterRaise = gameRound.getPlayerActions().size() - gameRound.getLastRaisedPointer() - 1;
			if(actionsAfterRaise == activePlayers - 1)
				return true;
		}
		
		return false;
	}
}
